<template>
    <div class="create-version-modal-wrap">
        <a-modal
            :visible="visible"
            :width="800"
            :title="form.id ? '编辑版本' : '新增版本'"
            okText="确认"
            cancelText="取消"
            @cancel="handleCancel"
            @ok="handleOk"
        >
            <a-form layout="inline" ref="ruleFormRef" :model="form" :rules="rules">
                <a-row>
                    <a-col :span="20">
                        <a-form-item label="PBI目录" name="catalogCode">
                            <span v-if="form.id">
                                {{ pbiName }}
                            </span>
                            <h-cascader
                                :change-on-select="true"
                                :default-value="systemInfo.catalogCode"
                                placeholder="请选择"
                                :options="pbiTreeData"
                                labelField="catalogName"
                                valueField="catalogCode"
                                show-search
                                childrenField="subNodes"
                                @change="handleCascaderChange($event, 'pbi')"
                                v-else
                            />
                        </a-form-item>
                    </a-col>
                    <a-col :span="20">
                        <a-form-item label="版本类型" name="type">
                            <!-- 子产品只能创建预发布版本 -->
                            <span v-if="form.id">
                                {{ $filters.versionControlVersionTypeFilter(form.type) }}
                            </span>
                            <a-select placeholder="请选择" v-model:value="form.type" @change="handleSelectTypeChange" v-else>
                                <a-select-option key="1" v-if="+systemInfo.catalogType <= 1"> 主线版本 </a-select-option>
                                <a-select-option key="2" v-if="+systemInfo.catalogType <= 1"> 支线版本 </a-select-option>
                                <a-select-option key="3"> 预发布版本 </a-select-option>
                            </a-select>
                        </a-form-item>
                    </a-col>
                    <a-col :span="20" v-if="+form.type > 1">
                        <a-form-item label="上级版本" name="parentId">
                            <h-cascader
                                :default-value="form.parentId"
                                :change-on-select="true"
                                placeholder="请选择"
                                :options="versionTreeData"
                                labelField="versionNumber"
                                valueField="id"
                                show-search
                                childrenField="subNodes"
                                @change="handleCascaderChange($event, 'versionNumber')"
                            />
                        </a-form-item>
                    </a-col>
                    <a-col :span="20">
                        <a-form-item label="版本号" name="versionNumber" class="version-number-form-item">
                            <span v-if="disabled">
                                {{ form.versionNumber }}
                            </span>
                            <div v-else>
                                <VersionNumberInput
                                    ref="versionNumberInputRef"
                                    :parentInfo="parentInfo"
                                    :systemInfo="systemInfo"
                                    :versionInfo="form"
                                    v-if="visible"
                                />
                            </div>
                        </a-form-item>
                    </a-col>
                    <a-col :span="20">
                        <a-form-item label="版本描述" name="description">
                            <span v-if="disabled">
                                {{ form.description }}
                            </span>
                            <a-textarea v-model:value="form.description" showCount :maxlength="200" auto-size v-else />
                        </a-form-item>
                    </a-col>
                    <a-col :span="20">
                        <a-form-item label="开发状态" name="status">
                            <span v-if="form.id"> {{ $filters.versionControlVersionStatusFilter(form.status, form.type) }} </span>
                            <a-select placeholder="请选择" v-model:value="form.status" @change="handleSelectStatusChange" v-else>
                                <a-select-option v-for="item of statusOptions" :key="item.value">
                                    {{ item.name }}
                                </a-select-option>
                            </a-select>
                        </a-form-item>
                    </a-col>
                    <a-col :span="20" v-if="+form.type === 1">
                        <a-form-item label="服务状态" name="serviceStatus">
                            <span v-if="form.id"> {{ $filters.versionServiceStatusFilter(form.serviceStatus) }} </span>
                            <a-select placeholder="请选择" v-model:value="form.serviceStatus" v-else>
                                <a-select-option v-for="item of serviceStatusOptions" :key="item.value">
                                    {{ item.name }}
                                </a-select-option>
                            </a-select>
                        </a-form-item>
                    </a-col>
                    <a-col :span="20" v-if="+form.type === 3">
                        <a-form-item label="迭代周期" name="startTime">
                            <HRangePickerCell
                                :placeholder="['请选择开始时间', '请选择上线时间']"
                                :value="[
                                    form['startTime'] ? $moment(form['startTime'], 'YYYY-MM-DD') : null,
                                    form['onlineTime'] ? $moment(form['onlineTime'], 'YYYY-MM-DD') : null,
                                ]"
                                @change="rangeDateChange"
                            />
                        </a-form-item>
                    </a-col>

                    <a-col :span="20" v-if="+form.type === 3">
                        <a-form-item label="开发阶段" name="randdEndTime">
                            <flexbox style="width: 100%">
                                <div>
                                    <HDatePickerCell :disabled="disabled" style="width: 200px" :value="form.startTime" />
                                    <span style="margin: 0 8px">~</span>
                                </div>
                                <HDatePickerCell :disabled="disabled" :disabledDate="false" style="width: 200px" v-model:value="form.randdEndTime" />
                            </flexbox>
                        </a-form-item>
                    </a-col>
                    <a-col :span="20" v-if="+form.type === 3">
                        <a-form-item label="测试阶段" name="testStartTime">
                            <flexbox style="width: 100%">
                                <HDatePickerCell :disabled="disabled" :disabledDate="false" style="width: 200px" v-model:value="form.testStartTime" />
                                <div>
                                    <span style="margin: 0 8px">~</span>
                                    <HDatePickerCell :disabled="disabled" style="width: 200px" :value="form.onlineTime" />
                                </div>
                            </flexbox>
                        </a-form-item>
                    </a-col>
                    <a-col :span="20" v-if="isUnifyRelease && +form.type === 3">
                        <a-form-item label="提示">
                            <div class="caption-font-color">
                                <span> 选中的产品将同步创建预发布版本流程</span>
                                <a-tooltip>
                                    <template #title>
                                        <span>仅产品经理有该系统权限时才可创建预发布版本</span>
                                    </template>
                                    <QuestionCircleOutlined class="margin-l-8" />
                                </a-tooltip>
                            </div>
                            <flexbox style="width: 100%">
                                <a-checkbox-group v-model:value="checkedList">
                                    <a-row>
                                        <a-col :span="8" v-for="item of subApplySystemList" :key="item.catalogCode">
                                            <a-checkbox
                                                :value="item.catalogCode"
                                                :disabled="versionInfo.id && oldCatalogCodeCv.indexOf(item.catalogCode) >= 0"
                                            >
                                                {{ item.catalogName }}
                                            </a-checkbox>
                                        </a-col>
                                    </a-row>
                                </a-checkbox-group>
                            </flexbox>
                        </a-form-item>
                    </a-col>
                </a-row>
            </a-form>
        </a-modal>
    </div>
</template>

<script lang="ts">
import api from '@/api';
import store from '@/store';
import VersionNumberInput from './VersionNumberInput.vue';
import { deepClone } from '@/utils/util';
import { message } from 'ant-design-vue';
import { treeFilter } from '@/utils/tree';
import { useMessage } from '@/hooks/common/useMessage';
import { QuestionCircleOutlined } from '@ant-design/icons-vue';
import { HCascader, HDatePickerCell, HRangePickerCell } from '@/components';
import { defineComponent, ref, unref, reactive, toRefs, computed, nextTick, onDeactivated } from 'vue';
export default defineComponent({
    components: {
        HCascader,
        HDatePickerCell,
        VersionNumberInput,
        HRangePickerCell,
        QuestionCircleOutlined
    },
    emits: ['success'],
    setup(_, { emit }) {
        const { createJiraLogin } = useMessage();
        const ruleFormRef = ref<any>();
        const versionNumberInputRef = ref<any>();
        const state = reactive<any>({
            visible: false,
            form: {
                id: null,
                versionNumber: '',
                description: '',
                type: null,
                status: '1',
                catalogCode: '',
                parentId: null,
                startTime: null,
                onlineTime: null,
                randdEndTime: null,
                randdStartTime: null,
                testStartTime: null,
                testEndTime: null,
                catalogCodeCv: null,
                serviceStatus: null
            },
            pbiTreeData: [],
            pbiName: '', // 回显pbi路径名称
            versionTreeData: [],
            systemInfo: {}, // 选择的产品或子产品信息
            proSystemInfo: {}, // 选择的产品信息
            versionInfo: {}, // type：1主线，2支线，3预发布版本，详情编辑时版本详情的信息
            parentInfo: {}, // 选择的上级版本
            statusOptions: [
                { name: '待开始', value: '1' },
                { name: '进行中', value: '2' },
                { name: '已结束', value: '3' }
            ],

            subApplySystemList: [],
            isUnifyRelease: null,
            checkedList: [],
            oldCatalogCodeCv: ''
        });
        const disabled = computed(() => {
            return !!(state.versionInfo.id && state.versionInfo.disableMessage);
        });
        const serviceStatusOptions = computed(() => {
            switch (state.form.status) {
                case '1':
                    return [{ name: '待建设', value: '1' }];
                case '2':
                    return [
                        { name: '实施中', value: '2' },
                        { name: '服务中', value: '3' },
                        { name: '计划下线', value: '4' }
                    ];
                case '3':
                    return [
                        { name: '服务中', value: '3' },
                        { name: '计划下线', value: '4' },
                        { name: '已下线', value: '5' }
                    ];
            }
        });
        const validateParentId = async (rule: any, value: any) => {
            // 主线版本
            if (state.form.type === '1') {
                return Promise.resolve();
            }
            // 预发布版本
            else if (+state.form.type === 3) {
                if (value) {
                    if (state.parentInfo.id) {
                        return +state.parentInfo.type === 2 ? Promise.resolve() : Promise.reject('请选择支线版本');
                    } else {
                        return ['L1', 'L2', 'L3'].includes(state.systemInfo.productGrade)
                            ? Promise.reject('L3及以上产品必须选择上级版本')
                            : Promise.resolve();
                    }
                } else {
                    return Promise.reject('上级版本不能为空');
                }
            } else {
                return value ? Promise.resolve() : Promise.reject('上级版本不能为空');
            }
        };
        const validateVersionNumber = async (rule: any, value: any) => {
            const res = await unref(versionNumberInputRef).validate();
            return !res ? Promise.reject('上级版本不能为空') : Promise.resolve();
        };
        const validateCatalogCode = async (rule: any, value: any) => {
            return state.systemInfo.catalogType > 0 ? Promise.resolve() : Promise.reject('请选择产品或子产品');
        };
        const validateRangeTime = async (rule: any, value: any) => {
            if (!state.form.onlineTime) {
                return Promise.reject('上线时间不能为空');
            } else {
                return Promise.resolve();
            }
        };
        const rules = computed(() => {
            let rules = {};
            if (state.form.id) {
                if (state.versionInfo.disableMessage) {
                    rules = {
                        parentId: [{ validator: validateParentId, trigger: 'change' }]
                    };
                } else {
                    rules = {
                        parentId: [{ validator: validateParentId, trigger: 'change' }],
                        versionNumber: [{ validator: validateVersionNumber, trigger: 'change' }],
                        startTime: [
                            { required: true, message: '开始时间不能为空', trigger: 'change' },
                            { validator: validateRangeTime, trigger: 'change' }
                        ]
                    };
                }
            } else {
                rules = {
                    catalogCode: [{ required: true, validator: validateCatalogCode, trigger: 'change' }],
                    type: [{ required: true, message: '版本类型不能为空', trigger: 'change' }],
                    parentId: [{ validator: validateParentId, trigger: 'change' }],
                    versionNumber: [{ validator: validateVersionNumber, trigger: 'change' }],
                    startTime: [
                        { required: true, message: '开始时间不能为空', trigger: 'change' },
                        { validator: validateRangeTime, trigger: 'change' }
                    ],
                    status: [{ required: true, message: '版本状态不能为空', trigger: 'change' }]
                };
                // 主线版本，服务状态必填
                if (+state.form.type === 1) {
                    rules = {
                        ...rules,
                        serviceStatus: [{ required: true, message: '服务状态不能为空', trigger: 'change' }]
                    };
                }
            }
            return rules;
        });
        // 用于选择某个固定层级下的版本
        const transformVersionDataByFlatProperty = (data, fields = { keyField: 'node', childrenField: 'subNodes' }) => {
            const { keyField, childrenField } = fields;
            data.forEach((item, index) => {
                data[index] = {
                    ...data[index],
                    ...data[index][keyField]
                };
                if (item[childrenField] && item[childrenField].length && +item.node.type < +state.form.type - 1) {
                    data[index][childrenField] = transformVersionDataByFlatProperty(item[childrenField], fields);
                } else {
                    data[index][childrenField] = null;
                }
            });
            return data;
        };
        // 编辑时不用显示统一发版子平台
        const open = ({ systemInfo, proSystemInfo = {}, versionInfo = {}, isUnifyRelease }) => {
            state.systemInfo = systemInfo;
            state.proSystemInfo = proSystemInfo;
            state.versionInfo = versionInfo;
            state.isUnifyRelease = isUnifyRelease;
            state.checkedList = [];
            state.parentInfo = {};
            getPbiTreeData();
            if (versionInfo) {
                state.form = {
                    ...state.form,
                    ...versionInfo
                };
                if (state.versionInfo.catalogCodeCv) {
                    state.checkedList = state.versionInfo.catalogCodeCv.split(',');
                    state.oldCatalogCodeCv = state.versionInfo.catalogCodeCv.split(',');
                } else {
                    state.oldCatalogCodeCv = '';
                }
                initTreeData(state.form.type);
                // 🈚️父级的
                if (+state.form.type === 3 && !state.form.parentId) {
                    state.form.parentId = -1;
                }
            } else {
                resetForm();
            }
            state.form.catalogCode = state.systemInfo.catalogCode;
            state.visible = true;
            nextTick(() => {
                unref(ruleFormRef).clearValidate();
            });
            if (state.isUnifyRelease) {
                getSubPro();
            }
        };
        // 获取子产品系统
        const getSubPro = async () => {
            const query = {
                catalogCode: state.systemInfo.catalogCode
            };
            const { success, moule } = await api.versionControlModel.getUserSubProductCatalogs(query);
            if (success) {
                state.subApplySystemList = [...moule];
            }
        };
        const handleCascaderChange = ({ nodeInfo }, field) => {
            switch (field) {
                case 'pbi':
                    state.systemInfo = nodeInfo;
                    state.form.catalogCode = state.systemInfo.catalogCode;
                    state.form.type = null;
                    break;
                case 'versionNumber':
                    if (nodeInfo.id < 0) {
                        state.form.parentId = -1;
                        state.parentInfo = {};
                    } else {
                        state.form.parentId = nodeInfo.id;
                        state.parentInfo = nodeInfo;
                    }
                    break;
            }
        };
        // 筛选某个catologcode下固定层级的版本
        const transformDataByFlatProperty = (data, fields = { keyField: 'node', childrenField: 'subNodes' }) => {
            const { keyField, childrenField } = fields;
            data.forEach((item, index) => {
                data[index] = {
                    ...data[index],
                    ...data[index][keyField]
                };
                if (item[childrenField] && item[childrenField].length && +item.node.type < 3) {
                    data[index][childrenField] = transformVersionDataByFlatProperty(item[childrenField], fields);
                } else {
                    data[index][childrenField] = null;
                }
            });
            return data;
        };
        // 获取子产品父级产品的树，用于游离版本绑定
        const getParentTreeList = async () => {
            let treeData: any = [];
            state.isTreeEmpty = false;
            const query = {
                catalogCode: state.proSystemInfo.catalogCode
            };
            let { success, moule } = await api.versionControlModel.getVersionTree(query);
            if (success) {
                moule = JSON.parse(moule);
                if (moule && moule.length) {
                    treeData = [...transformDataByFlatProperty(moule)];
                }
            }
            return treeData;
        };
        // 1.从已有树打开 2.从游离版本上打开
        const initTreeData = (val) => {
            // 判断子产品还是产品
            // 点击产品
            if (state.systemInfo.catalogType < 2) {
                // 支线版本
                if (+val === 2) {
                    state.versionTreeData = transformVersionDataByFlatProperty(deepClone(store.getters.versionTreeData));
                }
                // 预发布版本及游离版本
                else if (+val === 3) {
                    const versionTreeData = transformVersionDataByFlatProperty(deepClone(store.getters.versionTreeData));
                    state.versionTreeData = [{ versionNumber: '无', id: -1 }, ...versionTreeData];
                }
            }
            // 点击子产品
            else {
                // 因为子产品没有版本树，所以要获取产品的版本树
                getParentTreeList().then((res) => {
                    const versionTreeData: any = deepClone(res);
                    state.versionTreeData = [{ versionNumber: '无', id: -1 }, ...versionTreeData];
                });
            }
        };
        // 日期
        const rangeDateChange = (val) => {
            const { startTime, endTime } = val;
            state.form.startTime = startTime;
            state.form.onlineTime = endTime;
        };
        // 选择版本类型回调
        const handleSelectTypeChange = (val) => {
            state.form.parentId = null;
            state.parentInfo = {};
            // 如果选择非主线版本则清空服务状态字段
            if (val !== '1') {
                state.form.serviceStatus = null;
            }
            initTreeData(val);
        };
        const handleCancel = () => {
            state.visible = false;
            resetForm();
        };
        const handleOk = async () => {
            unref(ruleFormRef)
                .validate()
                .then(async () => {
                    if (+state.form.type === 3) {
                        state.form.randdStartTime = state.form.startTime;
                        state.form.testEndTime = state.form.onlineTime;
                    } else {
                        state.form.randdStartTime = null;
                        state.form.testEndTime = null;
                        state.form.startTime = null;
                        state.form.onlineTime = null;
                    }
                    if (!disabled.value) {
                        state.form.versionNumber = unref(versionNumberInputRef).versionNumber;
                    }
                    const query = {
                        ...state.form
                    };
                    // 统一发版本
                    if (state.isUnifyRelease) {
                        // 是否有旧的子产品记录
                        if (state.oldCatalogCodeCv) {
                            const arr: any = [];
                            state.checkedList.forEach((item) => {
                                if (state.oldCatalogCodeCv.indexOf(item) < 0) {
                                    arr.push(item);
                                }
                            });
                            if (arr.length) {
                                query.catalogCodeCv = arr.join(',');
                            } else {
                                query.catalogCodeCv = null;
                            }
                        } else {
                            query.catalogCodeCv = state.checkedList.length ? state.checkedList.join(',') : '';
                        }
                    } else {
                        query.catalogCodeCv = state.form.catalogCode;
                    }
                    if (query.parentId === -1) {
                        query.parentId = null;
                    }
                    const { success, errorMsg, errorCode } = await api.versionControlModel.save(query);
                    if (success) {
                        message.success(query.id ? '修改成功' : '新增成功');
                        emit('success');
                        state.visible = false;
                        resetForm();
                    } else {
                        if (errorCode === '003') {
                            createJiraLogin({
                                onOk() {
                                    handleOk();
                                }
                            });
                            return;
                        }
                        message.error(errorMsg);
                    }
                });
        };
        const resetForm = () => {
            state.form = {
                id: null,
                versionNumber: '',
                description: '',
                type: null,
                status: '1',
                catalogCode: '',
                parentId: null,
                startTime: null,
                onlineTime: null,
                randdEndTime: null,
                randdStartTime: null,
                testStartTime: null,
                testEndTime: null
            };
        };
        const transformPbiDataByFlatProperty = (data, fields = { keyField: 'node', childrenField: 'subNodes' }) => {
            const { keyField, childrenField } = fields;
            data.forEach((item, index) => {
                data[index] = {
                    ...data[index],
                    ...data[index][keyField],
                    catalogName: data[index][keyField].catalogName
                };
                if (item[childrenField] && item[childrenField].length && +item.node.catalogType < 2) {
                    data[index][childrenField] = transformPbiDataByFlatProperty(item[childrenField], fields);
                } else {
                    data[index][childrenField] = null;
                }
            });
            return data;
        };
        const getPbiName = (target, name) => {
            if (target && target.length) {
                if (name) {
                    name = `${name} / ${target[0].catalogName}`;
                } else {
                    name = target[0].catalogName;
                }
                return getPbiName(target[0].subNodes, name);
            }
            return name;
        };
        // 获取所有pbi数据
        const getPbiTreeData = async () => {
            const query = {
                type: 2
            };
            const { success, moule } = await api.portalControlModel.getSystemProductCatalogTreeData(query);
            if (success) {
                if (moule) {
                    state.pbiTreeData = transformPbiDataByFlatProperty(deepClone(JSON.parse(moule)));
                    const target = treeFilter(state.pbiTreeData, (node) => node.catalogCode === state.systemInfo.catalogCode);
                    state.pbiName = getPbiName(target, '');
                }
            }
        };
        // 版本状态发生改变后，校验当前选择的服务状态是否满足要求
        const handleSelectStatusChange = (val) => {
            if (state.form.serviceStatus) {
                const arr: any = serviceStatusOptions.value;
                const target = arr.find((item) => item.value === state.form.serviceStatus);
                if (!target) {
                    state.form.serviceStatus = null;
                }
            }
        };

        // 销毁时关闭弹窗
        onDeactivated(() => {
            state.visible = false;
        });

        return {
            rules,
            ruleFormRef,
            versionNumberInputRef,
            ...toRefs(state),
            serviceStatusOptions,
            disabled,
            open,
            handleCancel,
            handleOk,
            handleCascaderChange,
            handleSelectTypeChange,
            rangeDateChange,
            handleSelectStatusChange
        };
    }
});
</script>
<style lang="less" scoped>
::v-deep(.ant-form-inline .ant-form-item-label) {
    min-width: 160px !important;
}
::v-deep(.ant-checkbox-group) {
    width: 100% !important;
}
::v-deep(.apply-setting-item) {
    .ant-form-item-label > label::after {
        top: -11px !important;
    }
    .ant-form-item-label {
        width: 110px;
        white-space: pre-wrap !important;
        padding-top: 6px !important;
    }
}
::v-deep(.version-number-form-item) {
    .ant-form-item-explain-error {
        display: none;
    }
}
</style>